/**
 * 已修改从传统js转ts
 * @create zgf
 */
// let Cesium: any =undefined; 如果CesiumSources能引入过来就引入，尽量不要在每个ts都引用一遍
let Cesium:any=undefined;
interface CircleWaveMaterialPropertyOptions {
    duration?: number;
    color?: any;
    count?: number;
    gradient?: number;
}

/**
 * 波动圆材质
 * @global
 * @param {object} options
 * @param {number} options.duration - 持续时长
 * @param {Color} options.color - 颜色
 * @param {number} options.count -频率
 * @param {number} options.gradient - 渐进频率
 * @example
 *     const custMaterial =  new Cesium.Scene.CircleWaveMaterialProperty({
                  count: 2,
                  color:   Cesium.Color.BLUE,,
                  gradient: 0.3,
                  duration:60
                });
 */
class CircleWaveMaterialProperty extends Cesium.Property {
    private _definitionChanged: any;
    private _color: any;
    private _colorSubscription: any;
    private _duration: any;
    private _durationSubscription: any;
    public gradient: any
    public count: number

    constructor(options: CircleWaveMaterialPropertyOptions) {
        super()
        this._definitionChanged = new Cesium.Event();
        this._color = Cesium.defaultValue(options.color, Cesium.Color.fromBytes(0, 255, 255, 255));
        this._duration = Cesium.defaultValue(options.duration, 45);
        this.count = Math.max(Cesium.defaultValue(options.count, 2), 1);
        this.gradient = Cesium.defaultValue(options.gradient, 0.1);
        if (this.gradient < 0) {
            this.gradient = 0;
        } else if (this.gradient > 1) {
            this.gradient = 1;
        }
    }
    // @ts-ignore
    get isConstant(): boolean {
        return false;
    }
    // @ts-ignore
    get definitionChanged(): Cesium.Event {
        return this._definitionChanged;
    }

    get color(){
        return this._color;
    }

    set color(value) {
        this._color = value;
    }

    get duration() {
        return this._duration;
    }

    set duration(value: any) {
        this._duration = value;
    }

    getType(): string { //给这个材质定义一个类型  CircleWave
        // @ts-ignore
        return Cesium.Material.CircleWaveType;
    }

    getValue(time: any, result: any) {
        if (!result) {
            result = {};
        }
        result.color = Cesium.Property.getValueOrUndefined(this._color, time);
        result.duration = this._duration;
        result.count = this.count;
        result.gradient = this.gradient;
        return result;
    }

    equals(other: any) {
        return (
            this === other || (other instanceof CircleWaveMaterialProperty && Cesium.Property.equals(this._color, other._color))
        );
    }

}
function _getDynamicCircleShader(options: any) {
    if (options && options.get) {
        return "uniform vec4 color;\n\
              uniform float duration;\n\
              uniform float count;\n\
              uniform float gradient;\n\
              \n\
              czm_material czm_getMaterial(czm_materialInput materialInput)\n\
              {\n\
                  czm_material material = czm_getDefaultMaterial(materialInput);\n\
                  material.diffuse = 1.5 * color.rgb;\n\
                  vec2 st = materialInput.st;\n\
                  vec3 str = materialInput.str;\n\
                  float dis = distance(st, vec2(0.5, 0.5));\n\
                  float per = fract(czm_frameNumber / duration);\n\
                  if(abs(str.z) > 0.001){\n\
                      discard;\n\
                  }\n\
                  if(dis > 0.5){\n\
                      discard;\n\
                  } else {\n\
                      float perDis = 0.5 / count;\n\
                      float disNum;\n\
                      float bl = .0;\n\
                      for (int i = 0; i <= 10; i++) {\n\
                          if (float(i) <= count) {\n\
                              disNum = perDis * float(i) - dis + per / count;\n\
                              if (disNum > 0.0) {\n\
                                  if (disNum < perDis) {\n\
                                      bl = 1.0 - disNum / perDis;\n\
                                  } else if (disNum - perDis < perDis) {\n\
                                      bl = 1.0 - abs(1.0 - disNum / perDis);\n\
                                  }\n\
                                  material.alpha = pow(bl, gradient);\n\
                              }\n\
                          }\n\
                      }\n\
                  }\n\
                  return material;\n\
              }\n\
              ";
    }
}


const _installWaveCircleMaterial=(CesiumSpurces:any)=> {
   Cesium=CesiumSpurces;
    // @ts-ignore
    Cesium.Material.CircleWaveType = "CircleWave";
    // @ts-ignore
    Cesium.Scene.CircleWaveMaterialProperty = CircleWaveMaterialProperty;
    // @ts-ignore
    Cesium.Material._materialCache.addMaterial(Cesium.Material.CircleWaveType, {
        fabric: {
            type: Cesium.Material.CircleWaveType,
            uniforms: {
                color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
                duration: 45,
                count: 1,
                gradient: 0.1,
            },
            source: _getDynamicCircleShader({
                get: true,
            }),
        },
        translucent: function () {
            return true;
        },
    });
}

export {
    _installWaveCircleMaterial
}


